    //
//  MegafaunaOfDayController.m
//  Digital Seamonsters
//
//  Created by Adam Cue on 2/8/11.
//  Copyright Adam Cue 2011.
//
//  This program is licensed and distributed under the terms of the GNU General Public License.  
//	The text for the license can be found in the license.txt file in this project.
//

#import "MegafaunaOfDayController.h"
#import "JSON.h"
#import "MarineFetcher.h"
#import "MFOW.h"
#import "MFOWMedia.h"

#define MEDIA_WINDOW_HELP_VIEW         CGRectMake(27.0, 44.0, 404.0, 203.0)
#define MEGAFAUNA_PULLOUT_HELP_VIEW    CGRectMake(37.0, 406.0, 446.0, 115.0)
#define SAVE_RELOAD_HELP_VIEW          CGRectMake(570.0, 44.0, 401.0, 143.0)
#define DESCRIPTION_HELP_VIEW          CGRectMake(583.0, 480.0, 401.0, 163.0)
#define IMAGE_VIEW_HEIGHT              492
#define IMAGE_VIEW_HEIGHT_PADDING       20

static dispatch_queue_t megafaunaOfWeekQueue;

@interface MegafaunaOfDayController (Private)
#pragma mark SetupMethods
- (void)setupBackgroundView;
- (void)setupMegafaunaTableView;
- (void)setupNetworking;
- (void)setupHelpView;

#pragma mark UserActions
- (void)dismissTutorial;
- (void)initializeMegafauna:(NSString *)jsonString;
- (void)mediaClicked:(UIGestureRecognizer *)gestureRecognizer;
- (void)mediaPinched:(UIPinchGestureRecognizer *)gestureRecognizer;
- (void)refreshMegafauna;
- (void)loadRecentMegafauna;
- (void)cancel:(id)sender;

#pragma mark HelperMethods
- (void)initialLoadTimeout;
- (NSArray *)megafaunaFetchResults:(BOOL)recent;
- (void)showLoadingView:(NSString *)message;
- (void)hideLoadingView:(NSString *)message;
- (void)showCancelButton;
- (void)hideCancelButton;
- (void)moviePlayerDidFinish;
- (void)refocused;
- (void)startLoading;
- (void)checkNetworkStatus:(NSNotification *)notice;
- (void)displayMegafauna;
- (void)showTitleAndDescription:(int)mediaCount;
- (void)showImage:(NSDictionary *)imageInfo withIndex:(int)index;
- (void)showVideo:(NSDictionary *)videoInfo withIndex:(int)index;
- (void)showMegafaunaMedia:(MegafaunaOfDayMedia *)media;

#pragma mark CoreDataActions
- (void)saveMegafauna:(NSNumber *)recent;
- (void)loadMegafauna:(MFOW *)mfow;

@end

@implementation MegafaunaOfDayController

@synthesize cancelButton = _cancelButton;
@synthesize helpView = _helpView;
@synthesize megafauna = _megafauna;
@synthesize mfodTable = _mfodTable;
@synthesize connections = _connections;
@synthesize reach = _reach;
@synthesize expandingImage = _expandingImage;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
       if(!megafaunaOfWeekQueue) megafaunaOfWeekQueue = dispatch_queue_create("com.cachalot.MegafaunaOfWeek", NULL);
       _connections = [[NSMutableArray alloc] initWithCapacity:1];
       firstRun = YES;
       internetAvailable = NO;
       firstLoad = YES;
    }
    return self;
}

- (void)viewDidLoad {
   [super viewDidLoad];
   [self setupBackgroundView];
   [self setupMegafaunaTableView];
   [self setupNetworking];
   [self setupHelpView];
}

- (void)viewDidUnload {
   [super viewDidUnload];
   [[NSNotificationCenter defaultCenter] removeObserver:self];
	self.reach = nil;
}

- (void)viewWillAppear:(BOOL)animated{
	if(firstRun	== NO && (!leftForFullScreenVideo  || !leftForFullScreenImage)){
		[self checkForNewMegafauna];
      if(!_helpView && ![[NSUserDefaults standardUserDefaults] valueForKey:CACHALOT_MEGAFAUNA_TUTORIAL_KEY]){
         [self setupHelpView];
         [self.view addSubview:self.helpView];
         if(![[NSUserDefaults standardUserDefaults] valueForKey:CACHALOT_MEGAFAUNA_TUTORIAL_KEY]){
            [UIView animateWithDuration:0.4 delay:1.0 options:UIViewAnimationCurveLinear
                             animations:^{
                                self.helpView.alpha = 1.0;
                             }completion:nil];
         }
      }
	}
   if(leftForFullScreenVideo){
      [self moviePlayerDidFinish];
   }
	firstRun = NO;
   leftForFullScreenVideo = NO;
   leftForFullScreenImage = NO;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
   return interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight;
}

- (void)dealloc {
   self.cancelButton = nil;
   self.helpView = nil;
	self.megafauna = nil;
   self.mfodTable = nil;
   self.connections = nil;
   self.reach = nil;
   self.expandingImage = nil;
   
   [super dealloc];
}

#pragma mark SetupMethods

- (void) setupBackgroundView {
   UIImageView * backgroundView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"grid_background"]] autorelease];
   backgroundView.frame = self.view.frame;
   backgroundView.alpha = 0.3;
   [self.view addSubview:backgroundView];
   [self.view sendSubviewToBack:backgroundView];
   _loadingView.alpha = 0.0;
   _mainImageView.pagingEnabled = YES;
   _mainImageView.delegate = self;
   _description.backgroundColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.0];
}

- (void) setupMegafaunaTableView {
   if(self.mfodTable) self.mfodTable = nil;
   _mfodTable = [[MegafaunaOfDayTableViewController alloc] initWithStyle:UITableViewStylePlain];
	self.mfodTable.delegate = self;
	self.mfodTable.tableView.frame = CGRectMake(-320, 0, 320, 704);
	self.mfodTable.tableView.separatorColor = [UIColor darkGrayColor];
	self.mfodTable.tableView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.84];
	[self.view addSubview:self.mfodTable.tableView];
}

- (void) setupNetworking {
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refocused) name:UIApplicationWillEnterForegroundNotification object:nil];
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkNetworkStatus:) name:kReachabilityChangedNotification object:nil];
	_reach = [[Reachability reachabilityWithHostName:@"seamonster.ml.duke.edu"] retain];
	[self.reach startNotifier];
   [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(initialLoadTimeout) userInfo:nil repeats:NO];
   [self showLoadingView:@"Loading Megafauna..."];
}

- (void) setupHelpView {
   if(![[NSUserDefaults standardUserDefaults] valueForKey:CACHALOT_MEGAFAUNA_TUTORIAL_KEY]){
      _helpView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 1024.0, 704.0)];
      self.helpView.backgroundColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.66];
      UIImageView * mediaWindowHelpView = [[[UIImageView alloc] initWithFrame:MEDIA_WINDOW_HELP_VIEW] autorelease];
      mediaWindowHelpView.image = [UIImage imageNamed:@"media-window-help"];
      mediaWindowHelpView.userInteractionEnabled = NO;
      [self.helpView addSubview:mediaWindowHelpView];
      UIImageView * megafaunaPulloutHelpView = [[[UIImageView alloc] initWithFrame:MEGAFAUNA_PULLOUT_HELP_VIEW] autorelease];
      megafaunaPulloutHelpView.image = [UIImage imageNamed:@"megafauna-pullout-help"];
      megafaunaPulloutHelpView.userInteractionEnabled = NO;
      [self.helpView addSubview:megafaunaPulloutHelpView];
      UIImageView * saveReloadHelpView = [[[UIImageView alloc] initWithFrame:SAVE_RELOAD_HELP_VIEW] autorelease];
      saveReloadHelpView.image = [UIImage imageNamed:@"save-reload-help"];
      saveReloadHelpView.userInteractionEnabled = NO;
      [self.helpView addSubview:saveReloadHelpView];
      UIImageView * descriptionHelpView = [[[UIImageView alloc] initWithFrame:DESCRIPTION_HELP_VIEW] autorelease];
      descriptionHelpView.image = [UIImage imageNamed:@"description-help"];
      descriptionHelpView.userInteractionEnabled = NO;
      [self.helpView addSubview:descriptionHelpView];
      UITapGestureRecognizer * hideTutorialTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissTutorial)];
      [self.helpView addGestureRecognizer:hideTutorialTap];
      [hideTutorialTap release];
      UILabel * tutorialLabel = [[[UILabel alloc] initWithFrame:CGRectZero] autorelease];
      tutorialLabel.text = @"Tap anywhere to dismiss tutorial";
      tutorialLabel.textColor = [UIColor whiteColor];
      tutorialLabel.backgroundColor = [UIColor clearColor];
      tutorialLabel.font = [UIFont fontWithName:@"MarkerFelt-Thin" size:44.0];
      [tutorialLabel sizeToFit];
      tutorialLabel.center = self.helpView.center;
      [self.helpView addSubview:tutorialLabel];
      self.helpView.alpha = 0.0;
   }
}

#pragma mark UserActions
- (void) dismissTutorial {
   [[NSUserDefaults standardUserDefaults] setValue:[NSNumber numberWithBool:YES] forKey:CACHALOT_MEGAFAUNA_TUTORIAL_KEY];
   [UIView animateWithDuration:0.4 delay:0.0 options:UIViewAnimationCurveLinear 
                    animations:^{
                       self.helpView.alpha = 0.0;
                    } completion:^(BOOL finished){
                       [self.helpView removeFromSuperview];
                       self.helpView = nil;
                    }];
}

- (void)initializeMegafauna:(NSString *)jsonString{
   if(internetAvailable == NO)
   {
      [self loadRecentMegafauna];
      return;
   }
	internetAvailable = YES;
	BOOL isRecent = NO;
	newMegafauna = NO;
   NSString * urlString;
	if(jsonString == nil){
		isRecent = YES;
		newMegafauna = YES;
		urlString = [[[NSString alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:NEW_MFOW_URL]] encoding:NSUTF8StringEncoding] autorelease];
	}
   else{
      urlString = [[[NSString alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:jsonString]] encoding:NSUTF8StringEncoding] autorelease];
   }
	if(self.mfodTable.listOfMegafauna == nil){
		[self.mfodTable loadMegafaunaList];
	}
	NSDictionary *megafaunaDictionary = [urlString JSONValue];
	MegafaunaOfDay *selectedMegafauna = [[MegafaunaOfDay alloc] initWithName:[megafaunaDictionary objectForKey:@"name"] description:[megafaunaDictionary objectForKey:@"description"]];
	selectedMegafauna.isRecent = isRecent;
	self.megafauna = selectedMegafauna;
	[selectedMegafauna release];
	NSArray *megafaunaImages = [megafaunaDictionary objectForKey:@"media"];
   dispatch_async(dispatch_get_main_queue(), ^{[self showTitleAndDescription:[megafaunaImages count]];});
	int i = 0;
   for(int e = 0; e < [megafaunaImages count]; e++){
      [self.megafauna.media addObject:@"temp"];
      [self.connections addObject:@"conn"];
   }
	for(NSDictionary *megafaunaImage in megafaunaImages){
		if([[megafaunaImage objectForKey:@"type"] isEqualToString:@"image"]){
         dispatch_async(dispatch_get_main_queue(), ^{[self showImage:megafaunaImage withIndex:i];});
		}
		else if([[megafaunaImage objectForKey:@"type"] isEqualToString:@"video"]){
         dispatch_async(dispatch_get_main_queue(), ^{[self showVideo:megafaunaImage withIndex:i];});
		}
		i++;
	}
   dispatch_async(dispatch_get_main_queue(), ^{[self displayMegafauna];});
}

- (void)mediaClicked:(UIGestureRecognizer *)gestureRecognizer{
   if(self.expandingImage) return;
   int index = gestureRecognizer.view.tag - 1;
   if(index >= [self.megafauna.media count] || [[self.megafauna.media objectAtIndex:index] isEqual:@"temp"]) return;
	if([[self.megafauna.media objectAtIndex:gestureRecognizer.view.tag-1] fullImage] != nil){
		FullScreenMegafaunaViewController *fullScreenMegafaunaView = [[[FullScreenMegafaunaViewController alloc] init] autorelease];
		leftForFullScreenImage = YES;
		MegafaunaOfDayMedia *selected = [self.megafauna.media objectAtIndex:gestureRecognizer.view.tag-1];
		fullScreenMegafaunaView.fullImageView.image = selected.fullImage;
		fullScreenMegafaunaView.captionView.text = selected.caption;
      fullScreenMegafaunaView.name = self.megafauna.name;
      fullScreenMegafaunaView.delegate = self;
      _expandingImage = [[UIImageView alloc] initWithFrame:_mainImageView.frame];
      self.expandingImage.image = selected.fullImage;
      self.expandingImage.contentMode = UIViewContentModeScaleAspectFill;
      self.expandingImage.clipsToBounds = YES;
      self.expandingImage.left = _mainImageView.left;
      self.expandingImage.top = _mainImageView.top+IMAGE_VIEW_HEIGHT_PADDING;
      self.expandingImage.height = IMAGE_VIEW_HEIGHT;
      [self.tabBarController.view addSubview:self.expandingImage];
      [UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationCurveLinear 
                       animations:^{
                          self.expandingImage.frame = CGRectMake(0, IMAGE_VIEW_HEIGHT_PADDING, 1024, 748);
                       } completion:^(BOOL finished) {
                          [self presentModalViewController:fullScreenMegafaunaView animated:NO];
                          fullScreenMegafaunaView.fullImageView.image = selected.fullImage;
                          fullScreenMegafaunaView.captionView.text = selected.caption;
                          fullScreenMegafaunaView.name = self.megafauna.name;
                       }];
	}
	else{
		if(internetAvailable == NO){
			UIAlertView *noInternetAlert = [[[UIAlertView alloc] initWithTitle:@"Connection required!" message:@"Could not play video without Internet connection.  Retry once connected to the Internet." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] autorelease];
			[noInternetAlert show];
		}
		else{
         leftForFullScreenVideo = YES;
			MegafaunaOfDayMedia *med = [self.megafauna.media objectAtIndex:gestureRecognizer.view.tag-1];
			MPMoviePlayerViewController *moviePlayerVC = [[[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL URLWithString:med.videoURL]] autorelease];
			moviePlayerVC.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
         _expandingImage = [[UIImageView alloc] initWithFrame:_mainImageView.frame];
         self.expandingImage.contentMode = UIViewContentModeScaleAspectFill;
         self.expandingImage.image = med.thumbnailImage;
         self.expandingImage.clipsToBounds = YES;
         self.expandingImage.left = _mainImageView.left;
         self.expandingImage.top = _mainImageView.top+IMAGE_VIEW_HEIGHT_PADDING;
         self.expandingImage.height = IMAGE_VIEW_HEIGHT;
         [self.tabBarController.view addSubview:self.expandingImage];
         [UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationCurveLinear 
                          animations:^{
                             self.expandingImage.frame = CGRectMake(0, IMAGE_VIEW_HEIGHT_PADDING, 1024, 748);
                          } completion:^(BOOL finished) {
                             [self presentModalViewController:moviePlayerVC animated:NO];
                          }];
		}
	}
}

- (void)mediaPinched:(UIPinchGestureRecognizer *)gestureRecognizer {
   int index = gestureRecognizer.view.tag - 1;
   if(index >= [self.megafauna.media count] || [[self.megafauna.media objectAtIndex:index] isEqual:@"temp"]) return;
   if(gestureRecognizer.state == UIGestureRecognizerStateBegan){
      if(self.expandingImage == nil) {
         _mainImageView.hidden = YES;
         _imageCounter.hidden = YES;
         MegafaunaOfDayMedia *med = [self.megafauna.media objectAtIndex:gestureRecognizer.view.tag-1];
         _expandingImage = [[UIImageView alloc] initWithFrame:_mainImageView.frame];
         self.expandingImage.contentMode = UIViewContentModeScaleAspectFill;
         self.expandingImage.image = med.fullImage == nil ? med.thumbnailImage : med.fullImage;
         self.expandingImage.clipsToBounds = YES;
         self.expandingImage.left = _mainImageView.left;
         self.expandingImage.top = _mainImageView.top+IMAGE_VIEW_HEIGHT_PADDING;
         self.expandingImage.height = IMAGE_VIEW_HEIGHT;
         [self.tabBarController.view addSubview:self.expandingImage];
         curTransform = self.expandingImage.transform;
      }
      
      [UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationCurveLinear 
                       animations:^{
                          self.expandingImage.center = CGPointMake([gestureRecognizer locationInView:self.tabBarController.view].x, self.expandingImage.center.y);
                       } completion:nil];
   }
   else if(gestureRecognizer.state == UIGestureRecognizerStateChanged){
      if(gestureRecognizer.scale < 1.0){
         if(lastScale != 0.0) self.expandingImage.transform = CGAffineTransformMakeScale(gestureRecognizer.scale - (lastScale - 1), 
                                                                                         gestureRecognizer.scale - (lastScale - 1));
         else self.expandingImage.transform = CGAffineTransformMakeScale(gestureRecognizer.scale, gestureRecognizer.scale);
      }
      else{
         float scalee = 1 + (gestureRecognizer.scale - 1.0) * 0.6;
         float lastScalee = 1 + (lastScale - 1.0) * 0.6;
         if(lastScale != 0) self.expandingImage.transform = CGAffineTransformMakeScale(gestureRecognizer.scale - (lastScale - 1),
                                                                                       scalee - (lastScalee - 1));
         else self.expandingImage.transform = CGAffineTransformMakeScale(gestureRecognizer.scale, scalee);
      }
      lastScale = gestureRecognizer.scale;
      self.expandingImage.center = CGPointMake([gestureRecognizer locationInView:self.tabBarController.view].x, self.expandingImage.center.y);
      CGRect prevFrame = self.expandingImage.frame;
      self.expandingImage.transform = CGAffineTransformIdentity;
      self.expandingImage.frame = prevFrame;
   }
   else{
      if(self.expandingImage != nil){
         if(gestureRecognizer.scale > 1.3 && gestureRecognizer.scale > lastScale-.05){
            if([[self.megafauna.media objectAtIndex:gestureRecognizer.view.tag-1] fullImage] != nil){
               FullScreenMegafaunaViewController *fullScreenMegafaunaView = [[[FullScreenMegafaunaViewController alloc] init] autorelease];
               leftForFullScreenImage = YES;
               MegafaunaOfDayMedia *selected = [self.megafauna.media objectAtIndex:gestureRecognizer.view.tag-1];
               fullScreenMegafaunaView.fullImageView.image = selected.fullImage;
               fullScreenMegafaunaView.captionView.text = selected.caption;
               fullScreenMegafaunaView.name = self.megafauna.name;
               fullScreenMegafaunaView.delegate = self;
               [UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationCurveLinear 
                                animations:^{
                                   self.expandingImage.frame = CGRectMake(0, IMAGE_VIEW_HEIGHT_PADDING, 1024, 748);
                                } completion:^(BOOL finished) {
                                   _mainImageView.hidden = NO;
                                   _imageCounter.hidden = NO;
                                   [self presentModalViewController:fullScreenMegafaunaView animated:NO];
                                   fullScreenMegafaunaView.fullImageView.image = selected.fullImage;
                                   fullScreenMegafaunaView.captionView.text = selected.caption;
                                   fullScreenMegafaunaView.name = self.megafauna.name;
                                }];
            }
            else{
               leftForFullScreenVideo = YES;
               MegafaunaOfDayMedia *med = [self.megafauna.media objectAtIndex:gestureRecognizer.view.tag-1];
               MPMoviePlayerViewController *moviePlayerVC = [[[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL URLWithString:med.videoURL]] autorelease];
               moviePlayerVC.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
               [UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationCurveLinear 
                                animations:^{
                                   self.expandingImage.frame = CGRectMake(0, IMAGE_VIEW_HEIGHT_PADDING, 1024, 748);
                                } completion:^(BOOL finished) {
                                   _mainImageView.hidden = NO;
                                   _imageCounter.hidden = NO;
                                   [self presentModalViewController:moviePlayerVC animated:NO];
                                }];
            }
         }
         else{
            [UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationCurveLinear 
                             animations:^{
                                self.expandingImage.frame = CGRectMake(_mainImageView.left, _mainImageView.top+IMAGE_VIEW_HEIGHT_PADDING, _mainImageView.width, IMAGE_VIEW_HEIGHT);
                             } completion:^(BOOL finished){
                                _mainImageView.hidden = NO;
                                _imageCounter.hidden = NO;
                                [self.expandingImage removeFromSuperview];
                                self.expandingImage = nil;
                             }];
         }
      }
      lastScale = 0.0;
   }
}

- (void)refreshMegafauna{
	if(internetAvailable == NO){
      dispatch_async(dispatch_get_main_queue(), ^{
         [self hideLoadingView:@"Connection required."];
         UIAlertView *noInternetAlert = [[[UIAlertView alloc] initWithTitle:@"Connection required!" 
                                                                    message:@"Could not download latest Megafauna of the Week.  Check back when you have an internet connection or view one of your favorite megafauna" 
                                                                   delegate:nil 
                                                          cancelButtonTitle:@"OK" 
                                                          otherButtonTitles:nil] autorelease];
         [noInternetAlert show];
      });
		return;
	}
	[self initializeMegafauna:nil];
}

- (void)loadRecentMegafauna{
	NSArray * recentFetchResults = [self megafaunaFetchResults:YES];
	if([recentFetchResults count] == 0){
		NSString *path = [[NSBundle mainBundle] bundlePath];
		NSString *finalPath = [path stringByAppendingPathComponent:@"Default-Info.plist"];
		NSDictionary *plistData = [NSDictionary dictionaryWithContentsOfFile:finalPath];
		MegafaunaOfDay *selectedMegafauna = [[MegafaunaOfDay alloc] initWithName:[plistData objectForKey:@"name"] description:[plistData objectForKey:@"description"]];
		selectedMegafauna.isRecent = YES;
		self.megafauna = selectedMegafauna;
		[selectedMegafauna release];
      dispatch_async(dispatch_get_main_queue(), ^{[self showTitleAndDescription:[selectedMegafauna.media count]];});
		MegafaunaOfDayMedia *med1 = [[MegafaunaOfDayMedia alloc] initWithThumbnailImage:[UIImage imageNamed:@"default1_thumb"] fullImage:[UIImage imageNamed:@"default1"] caption:[plistData objectForKey:@"caption1"]];
		med1.isMain = YES;
		med1.thumbnailNumber = 0;
      dispatch_async(dispatch_get_main_queue(), ^{[self showMegafaunaMedia:med1];});
		[self.megafauna.media addObject:med1];
		[med1 release];
		MegafaunaOfDayMedia *med2 = [[MegafaunaOfDayMedia alloc] initWithThumbnailImage:[UIImage imageNamed:@"default2_thumb"] fullImage:[UIImage imageNamed:@"default2"] caption:[plistData objectForKey:@"caption2"]];
		med2.thumbnailNumber = 1;
		dispatch_async(dispatch_get_main_queue(), ^{[self showMegafaunaMedia:med2];});
		[self.megafauna.media addObject:med2];
		[med2 release];
		[self saveMegafauna:[NSNumber numberWithBool:YES]];
	}
   else{
      [self loadMegafauna:[recentFetchResults objectAtIndex:0]];
   }
	UIAlertView *noInternetAlert = [[[UIAlertView alloc] initWithTitle:@"Connection required!" 
                                                              message:@"Could not download latest Megafauna of the Week.  Check back when you have an internet connection or view one of your favorite megafauna" 
                                                             delegate:nil 
                                                    cancelButtonTitle:@"OK" 
                                                    otherButtonTitles:nil] autorelease];
	[noInternetAlert show];
	dispatch_async(dispatch_get_main_queue(), ^{[self hideLoadingView:@"Connection required."];});;
}

- (void)cancel:(id)sender{
   for(NSURLConnection * conn in self.connections){
      [conn cancel];
   }
   [self.connections removeAllObjects];
   [self hideCancelButton];
   [self hideLoadingView:@"Download canceled"];
}

#pragma mark HelperMethods
- (void)initialLoadTimeout{
   if(firstLoad == YES){
      dispatch_async(megafaunaOfWeekQueue, ^{[self initializeMegafauna:nil];});
   }
   firstLoad = NO;
}

- (NSArray *)megafaunaFetchResults:(BOOL)recent{
   NSFetchRequest *recentRequest = [[NSFetchRequest alloc] init];
	NSEntityDescription *recentEntity = [NSEntityDescription entityForName:@"MFOW" inManagedObjectContext:[[MarineFetcher sharedInstance] managedObjectContext]];
	[recentRequest setPredicate:[NSPredicate predicateWithFormat:@"isRecent == %@", [NSNumber numberWithBool:recent]]];
	[recentRequest setEntity:recentEntity];
	NSError *recentError;
	NSArray *recentFetchResults = [[[MarineFetcher sharedInstance] managedObjectContext] executeFetchRequest:recentRequest error:&recentError];
	[recentRequest release];
	if (recentFetchResults == nil) {
		NSLog(@"%@", recentError);
	}
   return recentFetchResults;
}

- (void)showLoadingView:(NSString *)message {
   _saveButton.enabled = NO;
   _refreshButton.enabled = NO;
   _showMegafaunaButton.enabled = NO;
   _loadingView.text = message;
   [UIView animateWithDuration:0.2 delay:0 options:UIViewAnimationCurveLinear 
                    animations:^{
                       _loadingView.alpha = 1.0;
                    } completion:nil];
}

- (void)hideLoadingView:(NSString *)message {
   _saveButton.enabled = YES;
   _refreshButton.enabled = YES;
   _showMegafaunaButton.enabled = YES;
   _loadingView.text = message;
   [UIView animateWithDuration:0.5 delay:1.2 options:UIViewAnimationCurveLinear 
                    animations:^{
                       _loadingView.alpha = 0.0;
                    } completion:nil];
}

- (void)showCancelButton {
   if(!_cancelButton){
      _cancelButton = [[UIBarButtonItem alloc] initWithTitle:@"Cancel" style:UIBarButtonItemStyleDone target:self action:@selector(cancel:)];
   }
   NSMutableArray * items = [_toolbar.items mutableCopy];
   [items insertObject:_cancelButton atIndex:0];
   [_toolbar setItems:items animated:YES];
}

- (void)hideCancelButton {
   [self.connections removeAllObjects];
   NSMutableArray * items = [_toolbar.items mutableCopy];
   [items removeObjectAtIndex:0];
   [_toolbar setItems:items animated:YES];
   self.cancelButton = nil;
}

- (void)moviePlayerDidFinish {
   if(self.expandingImage){
      [UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationCurveLinear 
                       animations:^{
                          self.expandingImage.frame = CGRectMake(_mainImageView.left, _mainImageView.top+IMAGE_VIEW_HEIGHT_PADDING, _mainImageView.width, IMAGE_VIEW_HEIGHT);
                       } completion:^(BOOL finished){
                          [self.expandingImage removeFromSuperview];
                          self.expandingImage = nil;
                       }];
   }
}

- (void)refocused{
	if(self.tabBarController.selectedIndex == 0){
		[self checkForNewMegafauna];
	}
}

- (void)startLoading{
	[self showLoadingView:@"Loading Megafauna..."];
   [UIView animateWithDuration:0.8 delay:0.0 options:UIViewAnimationCurveLinear 
                    animations:^{
                       _showMegafaunaButton.left = 0.0;
                       self.mfodTable.tableView.left = -320.0;
                       [_showMegafaunaButton setImage:[UIImage imageNamed:@"Megafauna_Pullout"] forState:UIControlStateNormal];
                    }completion:nil];
}

- (void)checkNetworkStatus:(NSNotification *)notice{
	NetworkStatus internetStatus = [self.reach currentReachabilityStatus];
	switch (internetStatus){
		case NotReachable:{
			internetAvailable = NO;
			break;
		}
		case ReachableViaWiFi:{
			internetAvailable = YES;
			[self.mfodTable loadMegafaunaList];
			break;
		}
		case ReachableViaWWAN:{
			internetAvailable = YES;
			[self.mfodTable loadMegafaunaList];
			break;
			
		}
	}
	if(firstLoad == YES){
      dispatch_async(megafaunaOfWeekQueue, ^{[self initializeMegafauna:nil];});
	}
	firstLoad = NO;
}

- (void)displayMegafauna{
	_mainImageView.contentSize = CGSizeMake([self.megafauna.media count] * _mainImageView.frame.size.width, _mainImageView.frame.size.height);
}

//Show the name and description of hte megafauna.
- (void)showTitleAndDescription:(int)mediaCount{
   _imageCounter.text = [NSString stringWithFormat:@"1/%d", mediaCount];
	_mainImageView.contentSize = CGSizeMake(_mainImageView.width, _mainImageView.height);
   for(UIView * subview in _mainImageView.subviews){
      [subview removeFromSuperview];
   }
	_nameLabel.text = self.megafauna.name;
	_description.contentOffset = CGPointMake(0, 0);
	if(self.megafauna.description != nil && [self.megafauna.description length] > 0){
		[_description setContentToHTMLString:self.megafauna.description];
   }
   [self showCancelButton];
}

- (void)showImage:(NSDictionary *)imageInfo withIndex:(int)index{
   MegafaunaOfTheWeekAsyncImageView *asyncImage = [[MegafaunaOfTheWeekAsyncImageView alloc] initWithFrame:CGRectMake(index * _mainImageView.width, 0, _mainImageView.width, _mainImageView.height)];
   UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(mediaClicked:)];
	[asyncImage addGestureRecognizer:tapGesture];
	[tapGesture release];
   UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(mediaPinched:)];
   [asyncImage addGestureRecognizer:pinchGesture];
   [pinchGesture release];
   asyncImage.delegate = self;
   asyncImage.info = imageInfo;
   asyncImage.index = index;
   [_mainImageView addSubview:asyncImage];
   [asyncImage loadImageFromURL:[NSURL URLWithString:[imageInfo objectForKey:@"path"]] withDefaultImage:nil];
   [asyncImage setSpinnerForLoading];
   [self.connections replaceObjectAtIndex:index withObject:asyncImage.connection];
   [asyncImage release];
}

- (void)showVideo:(NSDictionary *)videoInfo withIndex:(int)index{
   MegafaunaOfTheWeekAsyncImageView *asyncImage = [[MegafaunaOfTheWeekAsyncImageView alloc] initWithFrame:CGRectMake(index * _mainImageView.width, 0, _mainImageView.width, _mainImageView.height)];
   UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(mediaClicked:)];
	[asyncImage addGestureRecognizer:tapGesture];
	[tapGesture release];
   UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(mediaPinched:)];
   [asyncImage addGestureRecognizer:pinchGesture];
   [pinchGesture release];
   asyncImage.delegate = self;
   asyncImage.info = videoInfo;
   asyncImage.index = index;
   [_mainImageView addSubview:asyncImage];
   [asyncImage loadImageFromURL:[NSURL URLWithString:[videoInfo objectForKey:@"thumbnail_path"]] withDefaultImage:nil];
   [asyncImage setSpinnerForLoading];
   [self.connections replaceObjectAtIndex:index withObject:asyncImage.connection];
   [asyncImage release];
}

- (void)showMegafaunaMedia:(MegafaunaOfDayMedia *)media{
   MegafaunaOfTheWeekAsyncImageView *asyncImage = [[MegafaunaOfTheWeekAsyncImageView alloc] initWithFrame:CGRectMake(media.thumbnailNumber * _mainImageView.width, 0, _mainImageView.width, _mainImageView.height)];
   UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(mediaClicked:)];
	[asyncImage addGestureRecognizer:tapGesture];
	[tapGesture release];
   UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(mediaPinched:)];
   [asyncImage addGestureRecognizer:pinchGesture];
   [pinchGesture release];
   if(media.fullImage != nil){
      [asyncImage setDisplayImage:media.fullImage];
   }
   else{
      [asyncImage setDisplayImage:media.thumbnailImage];
   }
   asyncImage.tag = media.thumbnailNumber + 1;
   [_mainImageView addSubview:asyncImage];
   [asyncImage release];
}

#pragma mark ExternalMethods
- (IBAction)oldMegafauna:(id)sender{
   if(!_mfodTable) [self setupMegafaunaTableView];
   [UIView animateWithDuration:0.6 delay:0.0 options:UIViewAnimationCurveLinear 
                    animations:^{
                       if(self.mfodTable.tableView.frame.origin.x < 0){
                          [self.mfodTable.tableView reloadData];
                          _showMegafaunaButton.left = 319;
                          self.mfodTable.tableView.left = 0;
                          [_showMegafaunaButton setImage:[UIImage imageNamed:@"Hide_Pullout"] forState:UIControlStateNormal];
                       }
                       else{
                          _showMegafaunaButton.left = -1;
                          self.mfodTable.tableView.left = -320;
                          [_showMegafaunaButton setImage:[UIImage imageNamed:@"Megafauna_Pullout"] forState:UIControlStateNormal];
                       }
                    }completion:nil];
}

- (IBAction)refresh{
	[self showLoadingView:@"Loading Megafauna..."];
	dispatch_async(megafaunaOfWeekQueue, ^{[self refreshMegafauna];});	
}

- (IBAction)save{
	[self showLoadingView:@"Saving Megafauna..."];
	dispatch_async(megafaunaOfWeekQueue, ^{[self saveMegafauna:[NSNumber numberWithBool:NO]];});
}

- (void)checkForNewMegafauna{
	if(internetAvailable == YES){
		[self.mfodTable loadMegafaunaList];
		NSString *jsonString = [[[NSString alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://seamonster.ml.duke.edu/mfow?type=name"]] encoding:NSUTF8StringEncoding] autorelease];
		NSArray *recentFetchResults = [self megafaunaFetchResults:YES];
      NSString *recentName = [(MFOW *)[recentFetchResults objectAtIndex:0] name];
		NSString *latestName = [[jsonString JSONValue] objectForKey:@"name"];
		if([latestName isEqualToString:recentName] == NO){
			UIAlertView *recentView = [[[UIAlertView alloc] initWithTitle:@"New Megafauna Available!" message:@"Do you wish to download the latest Megafauna of the Week?" delegate:self cancelButtonTitle:@"No" otherButtonTitles:@"Yes", nil] autorelease];
			[recentView show];
			return;
		}
	}
}

#pragma mark FullScreenMegafaunaViewControllerDelegate
- (void)closeButtonPressed {
   [self dismissModalViewControllerAnimated:NO];
   [UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationCurveLinear 
                    animations:^{
                       self.expandingImage.frame = CGRectMake(_mainImageView.left, _mainImageView.top+IMAGE_VIEW_HEIGHT_PADDING, _mainImageView.width, IMAGE_VIEW_HEIGHT);
                    } completion:^(BOOL finished){
                       [self.expandingImage removeFromSuperview];
                       self.expandingImage = nil;
                    }];
}

#pragma mark UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
   if(((int)scrollView.contentOffset.x % (int)scrollView.frame.size.width) == 0){
      int shownImage = (int)(scrollView.contentOffset.x / scrollView.frame.size.width)+1;
      _imageCounter.text = [NSString stringWithFormat:@"%d/%d", shownImage, (int)(scrollView.contentSize.width / scrollView.width)];
   }
}

#pragma mark MegafaunaOfDayTableViewControllerDelegate
- (void)megafaunaClicked:(NSNumber *)megafaunaID{
	[self startLoading];
	NSString *jsonString = [NSString stringWithFormat:@"http://seamonster.ml.duke.edu/mfow?id=%d", [megafaunaID intValue]];
	dispatch_async(megafaunaOfWeekQueue, ^{[self initializeMegafauna:jsonString];});
}

- (void)savedMegafaunaClicked:(MFOW *)mfow{
	[self startLoading];
	dispatch_async(megafaunaOfWeekQueue, ^{[self loadMegafauna:mfow];});
}

#pragma mark UIAlertViewDelegate
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
	if(buttonIndex != 0){
		[self showLoadingView:@"Loading Megafauna..."];
      dispatch_async(megafaunaOfWeekQueue, ^{[self initializeMegafauna:nil];});
	}
}

#pragma mark MegafaunaOfTheWeekAsyncImageViewDelegate
- (void)imageView:(id)imageView downloadedImage:(UIImage *)image withIndex:(NSUInteger)index andInfo:(NSDictionary *)info{
   ((MegafaunaOfTheWeekAsyncImageView*) imageView).frame = CGRectMake(index * _mainImageView.frame.size.width, 0, _mainImageView.frame.size.width, _mainImageView.frame.size.height);
   ((MegafaunaOfTheWeekAsyncImageView*) imageView).tag = index+1;
   MegafaunaOfDayMedia *med;
   if([[info objectForKey:@"type"] isEqualToString:@"image"]){
      med = [[[MegafaunaOfDayMedia alloc] initWithThumbnailImage:nil fullImage:image caption:[info objectForKey:@"caption"]] autorelease];
      med.thumbnailNumber = index;
   }
   else if([[info objectForKey:@"type"] isEqualToString:@"video"]){
      med = [[[MegafaunaOfDayMedia alloc] initWithThumbnailImage:image videoURL:[info objectForKey:@"path"] caption:[info objectForKey:@"caption"]] autorelease];
      med.thumbnailNumber = index;
      UIImageView * playButton = [[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 167.0, 167.0)] autorelease];
      playButton.contentMode = UIViewContentModeScaleToFill;
      playButton.image = [UIImage imageNamed:@"play.png"];
      playButton.center = ((MegafaunaOfTheWeekAsyncImageView *) imageView).center;
      playButton.top -= 20;
      playButton.userInteractionEnabled = NO;
      [_mainImageView addSubview:playButton];
   }
   if([[info objectForKey:@"is_main"] intValue] == 1){
      med.isMain = YES;
   }
   [self.megafauna.media replaceObjectAtIndex:index withObject:med];
   BOOL ended = NO;
   for(id obj in self.megafauna.media){
      if([obj isEqual:@"temp"]){
         ended = YES;
      }
   }
   if(!ended){
      //self.slideshowTimer = [NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(changePhotos) userInfo:nil repeats:YES];
      dispatch_async(megafaunaOfWeekQueue, ^{
         if(newMegafauna){
            NSArray *recentFetchResults = [self megafaunaFetchResults:YES];
            if (recentFetchResults == nil) {
               NSLog(@"ERROR");
            }
            for(MFOW *mfow in recentFetchResults){
               [[[MarineFetcher sharedInstance] managedObjectContext] deleteObject:mfow];
            }
            [self saveMegafauna:[NSNumber numberWithBool:YES]];
         }
      });
      [self hideCancelButton];
      [self hideLoadingView:@"Megafauna Downloaded"];
      if(![[NSUserDefaults standardUserDefaults] valueForKey:CACHALOT_MEGAFAUNA_TUTORIAL_KEY]){
         [self.view addSubview:self.helpView];
         [UIView animateWithDuration:0.4 delay:1.0 options:UIViewAnimationCurveLinear
                          animations:^{
                             self.helpView.alpha = 1.0;
                          }completion:nil];
      }
   }
}

#pragma mark CoreData Actions
- (void)saveMegafauna:(NSNumber *)recent{
	if([recent boolValue] == NO){
		NSArray * recentFetchResults = [self megafaunaFetchResults:NO];
		for(MFOW *mfow in recentFetchResults){
			if([mfow.name isEqualToString:self.megafauna.name]){
				dispatch_async(dispatch_get_main_queue(), ^{[self hideLoadingView:@"Already saved!"];});
				return;
			}
		}
	}
	MFOW *toSave = [NSEntityDescription insertNewObjectForEntityForName:@"MFOW" inManagedObjectContext:[[MarineFetcher sharedInstance] managedObjectContext]];
	toSave.name = self.megafauna.name;
	toSave.desc = self.megafauna.description;
	toSave.isRecent = recent;
	for(MegafaunaOfDayMedia *med in self.megafauna.media){
		MFOWMedia *toSaveMedia = [NSEntityDescription insertNewObjectForEntityForName:@"MFOWMedia" inManagedObjectContext:[[MarineFetcher sharedInstance] managedObjectContext]];
		toSaveMedia.thumbnailImage = UIImagePNGRepresentation(med.thumbnailImage);
		if(med.fullImage == nil){
			toSaveMedia.moviePath = med.videoURL;
		}
		else{
			toSaveMedia.fullImage = UIImagePNGRepresentation(med.fullImage);
		}
		toSaveMedia.caption = med.caption;
		toSaveMedia.isMain = [NSNumber numberWithBool:med.isMain];
		toSaveMedia.thumbnailNumber = [NSNumber numberWithInt:med.thumbnailNumber];
		[toSave addMediaObject:toSaveMedia];
	}
	NSError *saveError;
	[[[MarineFetcher sharedInstance] managedObjectContext] save:&saveError];
	if([recent boolValue] == NO){
		dispatch_async(dispatch_get_main_queue(), ^{[self hideLoadingView:@"Megafauna Saved!"];});
	}
}

- (void)loadMegafauna:(MFOW *)mfow{
	MegafaunaOfDay *selectedMegafauna = [[MegafaunaOfDay alloc] initWithName:mfow.name description:mfow.desc];
	self.megafauna = selectedMegafauna;
	[selectedMegafauna release];
   dispatch_async(dispatch_get_main_queue(), ^{[self showTitleAndDescription:[mfow.media count]];});
	int i = 0;
	NSArray *mfowMedia = [mfow.media sortedArrayUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"thumbnailNumber" ascending:YES]]];
	for(MFOWMedia *mfowMed in mfowMedia){
		MegafaunaOfDayMedia *med;
		if(mfowMed.moviePath == nil){
			med = [[MegafaunaOfDayMedia alloc] initWithThumbnailImage:[UIImage imageWithData:mfowMed.thumbnailImage]
                                                         fullImage:[UIImage imageWithData:mfowMed.fullImage]
                                                           caption:mfowMed.caption];
		}
		else{
			med = [[MegafaunaOfDayMedia alloc] initWithThumbnailImage:[UIImage imageWithData:mfowMed.thumbnailImage] 
                                                          videoURL:mfowMed.moviePath 
                                                           caption:mfowMed.caption];
		}
		if([mfowMed.isMain boolValue] == 1){
			med.isMain = YES;
		}
		med.thumbnailNumber = i;
		dispatch_async(dispatch_get_main_queue(), ^{[self showMegafaunaMedia:med];});
		[self.megafauna.media addObject:med];
		[med release]; 
		i++;
	}
   dispatch_async(dispatch_get_main_queue(), ^{
      [self displayMegafauna];
      [self hideLoadingView:@"Megafauna Downloaded"];
   });
}

@end
